package com.heima.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.freemarker.FreemarkerGenerator;
import com.heima.file.MinIoTemplate;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.AutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.thread.UserThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private MinIoTemplate minIoTemplate;

    @Autowired
    private FreemarkerGenerator freemarkerGenerator;

    @Autowired
    private AutoScanService autoScanService;

    @Override
    public ResponseResult findList(WmNewsPageReqDto dto) {
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        Date beginPubDate = dto.getBeginPubDate();
        Integer channelId = dto.getChannelId();
        String keyword = dto.getKeyword();
        Short status = dto.getStatus();
        Integer currentPage = dto.getPage();
        Integer size = dto.getSize();
        Date endPubDate = dto.getEndPubDate();
        Page<WmNews> page = new Page<>(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper();
        //指定参数值查询
        wrapper.eq(status != null, WmNews::getStatus, status);
        wrapper.eq(channelId != null, WmNews::getChannelId, channelId);
        //模糊查询
        wrapper.like(StringUtils.isNoneEmpty(keyword), WmNews::getTitle, keyword);
        //构建排序条件
        wrapper.orderByDesc(WmNews::getPublishTime);
        //时间范围查询
        wrapper.between(beginPubDate != null && endPubDate != null, WmNews::getPublishTime, beginPubDate, endPubDate);
        Page<WmNews> wmNewsPage = this.baseMapper.selectPage(page, wrapper);
        Long total = wmNewsPage.getTotal();
        List<WmNews> records = wmNewsPage.getRecords();
        PageResponseResult pageResponseResult = new PageResponseResult(currentPage, size, total.intValue());
        pageResponseResult.setData(records);
        return pageResponseResult;

    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ResponseResult submit(WmNewsDto dto) {
        //提取新闻内容
        WmNews wmNews = wmNewsDto2WmNews(dto);
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        wmNews.setUserId(UserThreadLocal.get().getId());
        //插入新闻表
        int insert = wmNewsMapper.insert(wmNews);
        if (insert < 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        //判断是不是草稿
        Short status = dto.getStatus();
        if (status == 0) {//如果是草稿  将接收到的前端数据已经存入新闻表，结束操作
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }
        //下面属于如果本次操作不是草稿的情况
        String content = dto.getContent();
        //将所有content里的图片收集起来
        List<String> contentImage = getContentImage(content);
        //收集封面图
        List<String> images = dto.getImages();
        Short type = dto.getType();
        List<String> coverImages = getCoverImages(type, images, contentImage);
        //素材添加
        Boolean contentImagesResult = addMaterial(wmNews.getId(), coverImages, 0);
        if(!contentImagesResult){
            throw new RuntimeException("内容图添加失败");
        }
        //添加新闻素材关系
        Boolean coverImagesResult = addMaterial(wmNews.getId(), coverImages, 0);
        if(!coverImagesResult){
            throw new RuntimeException("封面图添加失败");
        }
        //调用审核代码
        try {
            autoScanService.autoScanWmNews(wmNews.getId().longValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    /**
     *  添加素材的方法
     * @param newsId
     * @param imageList
     * @param type  0是内容图  1 封面图
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean addMaterial(Integer newsId,List<String> imageList,Integer type){
        if(CollectionUtils.isEmpty(imageList)){
            return true;
        }
        //遍历
        for (String url : imageList) {
            if(StringUtils.isEmpty(url)){
                continue;
            }
            WmMaterial material = new WmMaterial();
            //组装数据
            material.setUserId(UserThreadLocal.get().getId());
            material.setUrl(url);
            material.setType((short)0);
            material.setIsCollection((short)0);
            material.setCreatedTime(new Date());
            int insert = wmMaterialMapper.insert(material);
            if(insert < 1){
                throw new RuntimeException("素材添加失败");
            }
            WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
            wmNewsMaterial.setMaterialId(material.getId());
            wmNewsMaterial.setNewsId(newsId);
            wmNewsMaterial.setType(type.shortValue());
            wmNewsMaterial.setOrd((short)1);
            int insert1 = wmNewsMaterialMapper.insert(wmNewsMaterial);
            if(insert1 < 1){
                throw new RuntimeException("新闻素材关系添加失败");
            }
        }
        return true;
    }

    //提取新闻内容的方法
    private WmNews wmNewsDto2WmNews(WmNewsDto wmNewsDto) {
        //先判断接收到的参数是否为空 非空的话，映射字段
        if (wmNewsDto == null) {
            return null;
        }
        //自动映射属性
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(wmNewsDto, wmNews);
        // 处理额外的字段
        // 就是入参没有包含但是返回值需要的字段
        // 也可以理解为返回参数的补全
        wmNews.setUserId(UserThreadLocal.get().getId());
        //设置创建时间
        wmNews.setCreatedTime(new Date());
        //设置enable
        wmNews.setEnable((short) 1);
        //判断传入的参数是否包含封面图片类型
        if (wmNewsDto.getType() == -1) {
            wmNews.setType(null);
        }
        //遍历封面图片images   将images转换成字符串存入wmNews
        List<String> images = wmNewsDto.getImages();
        if (!CollectionUtils.isEmpty(images)) {
            //将list集合里的每一条数据按照  ”，”  分割组合成字符串
            String join = StringUtils.join(images, ",");
            wmNews.setImages(join);
        }
        //内容全部提取，返回wmNews结果
        return wmNews;
    }

    //提取内容图
    private List<String> getContentImage(String content) {
        if (StringUtils.isEmpty(content)) {
            //如果content部分为空直接返回空集合
            return new ArrayList<>();
        }
        //不为空则获取图片内容
        //1.将content转换成集合
        List<Map> maps = JSON.parseArray(content, Map.class);
        if (CollectionUtils.isEmpty(maps)) {
            return new ArrayList<>();
        }
        //遍历集合
        List<String> list = new ArrayList<>();
        for (Map map : maps) {
            if (CollectionUtils.isEmpty(map)) {
                //这里不能直接返回，要继续循环直到遍历结束
                continue;
            }
            //获取type
            Object type = map.get("type");
            if ("image".equals(type)) {
                //
                String value = (String) map.get("value");
                list.add(value);
            }
        }
        return list;
    }

    //收集封面图的方法
    private List<String> getCoverImages(Short type, List<String> images, List<String> contentImages) {
        //自动布局的情况 需要获取content里的图片
        if (type == -1) {
            //判断content里面有几张
            int size = contentImages.size();
            if (size >= 3) {
                //由于封面最多三张图，所以这里是去前三张
                return contentImages.subList(0, 2);
            } else if (size == 0) {
                return new ArrayList<>();
            } else {
                return contentImages;
            }
        }
        //不是自动布局，直接返回封面images
        return images;
    }
}

